package com.jihui.jihuipicturebackend.controller;

import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jihui.jihuipicturebackend.annotation.CheckAuth;
import com.jihui.jihuipicturebackend.common.BaseResponse;
import com.jihui.jihuipicturebackend.common.ResultUtils;
import com.jihui.jihuipicturebackend.constant.UserConstant;
import com.jihui.jihuipicturebackend.exception.BusinessException;
import com.jihui.jihuipicturebackend.exception.ErrorCode;
import com.jihui.jihuipicturebackend.exception.ThrowUtils;
import com.jihui.jihuipicturebackend.manager.auth.SpaceUserAuthManager;
import com.jihui.jihuipicturebackend.model.dto.space.SpaceAddRequest;
import com.jihui.jihuipicturebackend.model.dto.space.SpaceLevel;
import com.jihui.jihuipicturebackend.model.dto.space.SpaceQueryRequest;
import com.jihui.jihuipicturebackend.model.dto.space.SpaceUpdateRequest;
import com.jihui.jihuipicturebackend.model.entity.Space;
import com.jihui.jihuipicturebackend.model.entity.User;
import com.jihui.jihuipicturebackend.model.enums.SpaceLevelEnum;
import com.jihui.jihuipicturebackend.model.vo.SpaceVO;

import com.jihui.jihuipicturebackend.service.SpaceService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/space")
@Slf4j
@Api(tags = "空间模块")
public class SpaceController {

    @Resource
    private SpaceService spaceService;

    @Resource
    private SpaceUserAuthManager spaceUserAuthManager;

    /**
     * 创建空间,所有人都可以使用
     * @param spaceAddRequest
     * @return
     */
    @PostMapping("/add")
    @ApiOperation(value = "创建空间")
    public BaseResponse<Long> addSpace(@RequestBody SpaceAddRequest spaceAddRequest,HttpServletRequest httpServletRequest) {
        ThrowUtils.throwIf(spaceAddRequest == null,ErrorCode.PARAMS_ERROR,"请求参数不能为空");
        User loginUser = (User) httpServletRequest.getSession().getAttribute(UserConstant.USER_LOGIN_STATE);
        long spaceId = spaceService.addSpace(spaceAddRequest, loginUser);
        return ResultUtils.success(spaceId);
    }

    /**
     * 删除空间
     * @param spaceId
     * @param httpServletRequest
     * @return
     */
    @DeleteMapping("/delete/spaceId")
    @ApiOperation(value = "删除空间")public BaseResponse<Boolean> deleteSpaceById(@RequestParam("spaceId") Long spaceId,
                                                                            HttpServletRequest httpServletRequest){
        // 校验参数
        ThrowUtils.throwIf(spaceId == null,
                new BusinessException(ErrorCode.PARAMS_ERROR,"空间ID不能为空"));
        // 校验空间是否存在
        Space space = spaceService.getById(spaceId);
        ThrowUtils.throwIf(space == null,
                new BusinessException(ErrorCode.OPERATION_ERROR,"空间不存在"));
        // 仅管理员和用户自己可以删除空间
        User loginUser = (User) httpServletRequest.getSession().getAttribute(UserConstant.USER_LOGIN_STATE);
        Long userId = space.getUserId();
        if(!userId.equals(loginUser.getId()) &&
                !loginUser.getUserRole().equals(UserConstant.ADMIN_ROLE)){
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无权限编辑空间信息");
        }
        // 删除空间
        ThrowUtils.throwIf(!spaceService.deleteSpaceById(spaceId),
                new BusinessException(ErrorCode.OPERATION_ERROR,"空间删除失败"));
        return ResultUtils.success(true);
    }

    /**
     * 跟新空间信息
     * @param spaceUpdateRequest
     * @param httpServletRequest
     * @return
     */
    @PostMapping("/update")
    @ApiOperation(value = "更新空间信息")
    @CheckAuth(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<SpaceVO> updateSpace(@RequestBody SpaceUpdateRequest spaceUpdateRequest, HttpServletRequest httpServletRequest) {
        // 校验空间上传请求
        User loginUser = (User) httpServletRequest.getSession().getAttribute(UserConstant.USER_LOGIN_STATE);
        SpaceVO spaceVO = spaceService.updateSpace(spaceUpdateRequest, loginUser);
        ThrowUtils.throwIf(spaceVO == null,
                new BusinessException(ErrorCode.OPERATION_ERROR,"空间更新失败"));
        return ResultUtils.success(spaceVO);
    }

    /**
     * 获取单个空间信息
     * @param spaceQueryRequest
     * @return
     */
    @PostMapping("/getSpaceVo")
    @ApiOperation(value = "获取单个空间信息")
    public BaseResponse<SpaceVO> getSpace(@RequestBody SpaceQueryRequest spaceQueryRequest,HttpServletRequest httpServletRequest){
        // 校验参数
        ThrowUtils.throwIf(spaceQueryRequest == null,
                new BusinessException(ErrorCode.PARAMS_ERROR,"查询请求不能为空"));
        // 查询空间
        SpaceVO spaceVO = spaceService.getSpaceVO(spaceQueryRequest);
        // 进行权限校验
        User loginUser = (User) httpServletRequest.getSession().getAttribute(UserConstant.USER_LOGIN_STATE);
        List<String> permissionList = spaceUserAuthManager.getPermissionList(SpaceVO.voToObj(spaceVO), loginUser);
        spaceVO.setPermissionList(permissionList);
        return ResultUtils.success(spaceVO);
    }

    /**
     * 分页获取空间vo信息(脱敏)
     * @param spaceQueryRequest
     * @param httpServletRequest
     * @return
     */
    @PostMapping("/list/page/vo")
    @CheckAuth(mustRole = UserConstant.ADMIN_ROLE)
    @ApiOperation(value = "分页获取空间vo信息")
    public BaseResponse<Page<SpaceVO>> getSpaceListVO(@RequestBody SpaceQueryRequest spaceQueryRequest,
                                                          HttpServletRequest httpServletRequest){
        ThrowUtils.throwIf(ObjUtil.isEmpty(spaceQueryRequest),
                new BusinessException(ErrorCode.PARAMS_ERROR, "分页查询参数不能为空"));
        long current = spaceQueryRequest.getCurrent();
        long size = spaceQueryRequest.getPageSize();
        QueryWrapper<Space> pictureQueryWrapper = spaceService.getSpaceQueryWrapper(spaceQueryRequest);
        Page<Space> picturePage = spaceService.page(new Page<>(current,size),pictureQueryWrapper);
        // 将Space转换为SpaceVO
        Page<SpaceVO> SpaceListVO = spaceService.getSpaceListVO(picturePage, httpServletRequest);
        return ResultUtils.success(SpaceListVO);
    }

    /**
     * 获取空间等级列表,用于前端下拉框选择
     * @return
     */
    @GetMapping("/list/level")
    public BaseResponse<List<SpaceLevel>> listSpaceLevel() {
        List<SpaceLevel> spaceLevelList = Arrays.stream(SpaceLevelEnum.values()) // 获取所有枚举
                .map(spaceLevelEnum -> new SpaceLevel(
                        spaceLevelEnum.getValue(),
                        spaceLevelEnum.getText(),
                        spaceLevelEnum.getMaxCount(),
                        spaceLevelEnum.getMaxSize()))
                .collect(Collectors.toList());
        return ResultUtils.success(spaceLevelList);
    }
}
